package nl.saxion.security.test;



import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

import javax.crypto.SealedObject;

import nl.saxion.security.encryption.TransformerAES;
import junit.framework.*;

public class TransformerAEStest extends TestCase {

	private TransformerAES transformer;

	public static Test suite() {
		return new TestSuite(TransformerAEStest.class);
	}

	public static void main(String[] args) {
		junit.textui.TestRunner.run(suite());
	}

	public void setUp() {
		transformer = new TransformerAES();
	}

	public void tearDown() {
		transformer = null;
	}

	public void testClasse() {
		assertNotNull(transformer);
	}

	public void testKey() {
		byte[] key = null;
		try {
			key = transformer.generateKey("testkey");
		} catch (Exception e) {

			e.printStackTrace();
		}
		assertNotNull(key);
		assertEquals(32, key.length);
		System.out.println("the generated key  :" + transformer.asHex(key));
	}

	public void testKey2() {
		byte[] key = null;
		try {
			key = transformer.generateKey("testkey");
		} catch (Exception e) {
			e.printStackTrace();
		}
		assertEquals(32, key.length);
		System.out.println("the generated key2 :" + transformer.asHex(key));
	}

	public void testEncrypt() {
		String original = "Dit is een test";
		

		byte[] encrypted = null;
		try {
			byte[] key = transformer.generateKey("Dit is een key");
			encrypted = transformer.encryptText(key, original);
		} catch (Exception e) {

			e.printStackTrace();
		}
		//System.out.println("encrypted key: " + transformer.asHex(encrypted));
		assertNotNull(encrypted);
		assertNotSame(original, encrypted);
	}

	public void testDecrypt() throws Exception {
		String original = "Dit is een test";

		byte[] encrypted = null;
		byte[] key = transformer.generateKey("Dit is een key");

		encrypted = transformer.encryptText(key, original);
		
		String retrievedString = null;

		retrievedString = transformer.decryptText(key, encrypted);

		assertEquals(original, retrievedString);
	}

	public void testWrongKey() throws Exception {
		String original = "Dit is een test";
		byte[] key = transformer.generateKey("Dit is een key");
		byte[] falseKey = transformer.generateKey("Dit is een false key");

		byte[] encrypted = null;

		try {
			encrypted = transformer.encryptText(key, original);
		} catch (Exception e1) {

			e1.printStackTrace();
		}
		assertNotNull(encrypted);
		assertNotSame(original, encrypted);
		String retrievedString = null;
		try {
			retrievedString = transformer.decryptText(falseKey, encrypted);
		} catch (Exception e) {
			//System.out.println("False Key");
		}
		assertNull(retrievedString);
	}
	
	public void testEncryptFile() throws Exception{
    	byte[] key = transformer.generateKey("this is a key");
    	String path = System.getProperty("user.dir");
    	String fileLocation = path + "\\testfile\\test.txt";
    	
    	//System.out.println(fileLocation);

		transformer.encryptFile(key, fileLocation, path + "\\testfile\\testENCRYPTED.txt");
    }
    
    
    public void testDecryptFile() throws Exception{
    	byte[] key = transformer.generateKey("this is a key");
    	String path = System.getProperty("user.dir");
    	String fileLocation = path + "\\testfile\\testENCRYPTED.txt";
    	
    	//System.out.println(fileLocation);
    	

		transformer.decryptFile(key, fileLocation, path + "\\testfile\\testDECRYPTED.txt");
    	    	
    }
    
    public void testgenerateKey() {
    	byte[] key = null;
		try {
			key = transformer.generateKey("Test");
		} catch (Exception e) {

			e.printStackTrace();
		}
		assertNotNull(key);
		//System.out.println("Generate key  :" + transformer.asHex(key));
    	
    }


    public void testEncryptDecryptObject() throws Exception {
    	byte[] key = transformer.generateKey("this is a key");
    	ArrayList<File> androidFiles = new ArrayList<File>();
    	SealedObject encryptedObj = null;
    	File file1 = new File("\\testfile\\file1.txt");
    	File file2 = new File("\\testfile\\file2.txt");
    	File file3 = new File("\\testfile\\file1.txt");
    	File file4 = new File("\\testfile\\file2.txt");
    	
    	androidFiles.add(file1);
    	androidFiles.add(file2);
    	androidFiles.add(file3);
    	androidFiles.add(file4);
    	System.out.println("Original: " + androidFiles.toString());

		encryptedObj = transformer.encryptObject(key, androidFiles);

    	
    	System.out.println("Encrypted Object= " + encryptedObj.toString());
    	
    	ArrayList<File> decryptedFiles = new ArrayList<File>();
    	Object obj = null;
    	
		obj = transformer.decryptObject(key, encryptedObj);

    	
    	
    	decryptedFiles = (ArrayList<File>) obj;
    	System.out.println("Decrypted: " + decryptedFiles.toString());
    	
    	assertEquals(androidFiles, decryptedFiles);  
    	
    
    }
    
    public void testFalseEncryptDecryptObject() throws Exception{
    	byte[] key = transformer.generateKey("this is a key");
    	byte[] falsekey = transformer.generateKey("this is a false key");
    	
    	
    	ArrayList<File> androidFiles = new ArrayList<File>();
    	SealedObject encryptedObj = null;
    	File file1 = new File("\\testfile\\file1.txt");
    	File file2 = new File("\\testfile\\file2.txt");
    	File file3 = new File("\\testfile\\file1.txt");
    	File file4 = new File("\\testfile\\file2.txt");
    	
    	androidFiles.add(file1);
    	androidFiles.add(file2);
    	androidFiles.add(file3);
    	androidFiles.add(file4);
    	

		encryptedObj = transformer.encryptObject(key, androidFiles);
    	
    	ArrayList<File> decryptedFiles = new ArrayList<File>();
    	Object obj = null;
    	
		try {
			obj = transformer.decryptObject(falsekey, encryptedObj);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("CANNOT DECRYPT");
		}
	
    	decryptedFiles = (ArrayList<File>) obj;
    	
    	assertNull(obj);
    	assertFalse(androidFiles.equals(decryptedFiles));
    }

    
    
    
    public void testHashSame() throws Exception{
    	
    	//first encrypt a file and decrypt it, then compare them
    	byte[] key = transformer.generateKey("this is a key");
    	String path = System.getProperty("user.dir");
    	String fileLocation = path + "\\testfile\\hash.txt";
    	//encrypt
		transformer.encryptFile(key, fileLocation, path + "\\testfile\\hashENCRYPTED.txt");

    	//decrypt
    	String encryptedFileLocation = path + "\\testfile\\hashENCRYPTED.txt";
		transformer.decryptFile(key, encryptedFileLocation, path + "\\testfile\\hashDECRYPTED.txt");

    	
    	
    	//generate a hash for the first file
    	String file1 = transformer.generateHash(path + "\\testfile\\hash.txt");
    	String file2 = transformer.generateHash(path + "\\testfile\\hashDECRYPTED.txt");

    	
    	assertEquals(file1, file2);
    	assertNotNull(file1, file2);
    	
    }
    
    public void testWriteFile() throws Exception{
    	String path = System.getProperty("user.dir");
    	byte[] key = transformer.generateKey("this is a key");
    	
    	File file1 = new File( path + "\\testfile\\hash.txt");
    	
		FileInputStream input = new FileInputStream(file1);

		byte[] plainData = new byte[(int) file1.length()];

		input.read(plainData);
		input.close();
	    	
    	
    	byte[] encryptedFile = null;

    	encryptedFile = transformer.encryptFileReturn(key, file1);

    	assertNotSame(plainData, encryptedFile);
    	
     	
    	
		FileInputStream fstream = new FileInputStream(file1);
		  // Get the object of DataInputStream
		DataInputStream in = new DataInputStream(fstream);
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		String strLine;
		//Read File Line By Line
		while ((strLine = br.readLine()) != null)   {
			// Print the content on the console
			System.out.println (strLine);
		}
		//Close the input stream
		in.close();
    	
    	
   

    }
    
    public void testKeyWithPassword() throws Exception {
		String generated = "98483c6eb40b6c31a448c22a66ded3b5e5e8d5119cac8327b655c8b5c4836489"; 
		//gegenereerd door het systeem
		byte[] password = transformer.generateKey("this is a key");
		//weet alleen de gebruiker
		
		//nu moet deze key versleuteld worden met het wachtwoord

		byte[] encrypted = encrypted = transformer.encryptText(password, generated);
		System.out.println("The encrypted key: " + transformer.asHex(encrypted));
		
		//decrypt
		String retrievedString = retrievedString = transformer.decryptText(password, encrypted);
		assertNotNull(retrievedString);
		
		System.out.println("The retrieved key: " + retrievedString);
	}
    
    
    public void testKeyWithFalsePassword() throws Exception {
    	String generated = "98483c6eb40b6c31a448c22a66ded3b5e5e8d5119cac8327b655c8b5c4836489"; 
		//gegenereerd door het systeem
		byte[] password = transformer.generateKey("this is a key");
		byte[] falsePassword = transformer.generateKey("this is a fasle asdf key");
		//weet alleen de gebruiker
		
		//nu moet deze key versleuteld worden met het wachtwoord

		byte[] encrypted = encrypted = transformer.encryptText(password, generated);
		System.out.println("The encrypted key: " + transformer.asHex(encrypted));
		
		//decrypt
		String retrievedString = null;
		try {
			retrievedString = retrievedString = transformer.decryptText(falsePassword, encrypted);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("CANNOT DECRYPT");
		}
		assertNull(retrievedString);
		
		System.out.println("The retrieved key: " + retrievedString);
  	}
    
    public void testRandomKey(){
    	byte[] key = null;
    	try {
			key = transformer.generateRandomKey();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	assertNotNull(key);
    	System.out.println("generated key: " + transformer.asHex(key));
    }
    
    public void testSalt() throws Exception{
    	
    	//first generate a hash from the passwrd;
    	byte[] wachtwoord = transformer.generateKey("wachtwoord");
    	
    	//generate salt
    	byte[] salt = transformer.generateRandomSalt();

    	
    	System.out.println("Wachtwoord: " + transformer.asHex(wachtwoord) + " Salt: " + transformer.asHex(salt));
    	
    	byte[] hashedPwdWithSalt = transformer.encryptBytes(salt, wachtwoord);
    	
    	System.out.println("Gen: " + transformer.asHex(hashedPwdWithSalt));
    	
    	//retrieve
    	byte[] originalPass = transformer.decryptBytes(salt, hashedPwdWithSalt);
    	
    	//save: salt en hashedPwdWithSalt
    			
    	System.out.println("Retrieved: " + transformer.asHex(originalPass));
    	assertNotNull(salt);
    	assertNotNull(hashedPwdWithSalt);
    }
    


}
